/**
 * Alibaba.com.cn Inc.
 * Copyright (c) 2004-2021 All Rights Reserved.
 */
package com.smart.service.impl;

import com.smart.common.enums.ErrorCode;
import com.smart.common.enums.OperateUserStatusEnum;
import com.smart.common.request.LoginRequest;
import com.smart.common.utils.AssertUtil;
import com.smart.context.SessionContext;
import com.smart.mapper.OperatePermissionMapper;
import com.smart.mapper.OperateRoleMapper;
import com.smart.model.domain.JiansheUnitDO;
import com.smart.model.domain.OperatePermissionDO;
import com.smart.model.domain.OperateRoleDO;
import com.smart.model.domain.OperateUserDO;
import com.smart.model.domain.ProjectDO;
import com.smart.model.domain.SuperviseUserDO;
import com.smart.model.dtomapper.JiansheUnitDtoMapper;
import com.smart.model.dtomapper.OperatePermissionDtoMapper;
import com.smart.model.dtomapper.OperateUserDtoMapper;
import com.smart.model.dtomapper.ProjectDtoMapper;
import com.smart.model.dtomapper.SuperviseUserDtoMapper;
import com.smart.model.vo.JiansheUnitVO;
import com.smart.model.vo.OperatePermissionVO;
import com.smart.model.vo.OperateUserVO;
import com.smart.model.vo.ProjectVO;
import com.smart.model.vo.SuperviseUserVO;
import com.smart.service.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhanghong
 * @version CommonUserServiceImpl.java, v 0.1 2023/6/19 17:31 下午 CommonUserServiceImpl Exp $$
 */
@Service
public class CommonUserServiceImpl implements CommonUserService {

    @Autowired
    private SuperviseUserService superviseUserService;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private JiansheUnitService jiansheUnitService;
    @Autowired
    private OperateUserService operateUserService;
    @Autowired
    private OperateRoleMapper operateRoleMapper;
    @Autowired
    private OperatePermissionMapper operatePermissionMapper;

    @Override
    public SuperviseUserVO superviseLogin(LoginRequest request) {
        AssertUtil.assertNotNull(request.getAccount(), "账号不能为空");
        AssertUtil.assertNotNull(request.getPassword(), "密码不能为空");

        //密码输入错误，若忘记密码请联系建委平台管理员进行修改
        SuperviseUserDO userDO = superviseUserService.lambdaQuery()
                .eq(SuperviseUserDO::getAccount, request.getAccount())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(userDO, "用户不存在");
        AssertUtil.assertTrue(Objects.equals(request.getPassword(), userDO.getPassword()), ErrorCode.PASSWORD_ERROR);
        return SuperviseUserDtoMapper.INSTANCE.do2VO(userDO);
    }

    @Override
    public SuperviseUserVO superviseMe() {
        Long superviseUserId = SessionContext.getSuperviseUserId();
        AssertUtil.assertNotNull(superviseUserId, ErrorCode.LOGIN_INVALID);
        return superviseUserService.getByKey(superviseUserId);
    }

    @Override
    public ProjectVO serviceLogin(LoginRequest request) {
        String account = request.getAccount();
        String password = request.getPassword();
        AssertUtil.assertNotNull(account, "账号不能为空");
        AssertUtil.assertNotNull(password, "密码不能为空");

        ProjectDO projectDO = projectService.lambdaQuery()
                .eq(ProjectDO::getAccount, request.getAccount())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(projectDO, ErrorCode.ACCOUNT_NOT_EXIST_ERROR);
        AssertUtil.assertTrue(!"REJECT".equals(projectDO.getAuditStatus()), "经建委审核,您注册的项目不存在,登录失败");
        AssertUtil.assertTrue(!"NEW".equals(projectDO.getAuditType()), "您注册的项目信息建委审核中，审核通过后方可登录");
        AssertUtil.assertTrue(projectDO.getDeleted()==0, "您登录的账号不存在");
        AssertUtil.assertTrue(Objects.equals(request.getPassword(), projectDO.getPassword()), ErrorCode.PASSWORD_ERROR);
        return ProjectDtoMapper.INSTANCE.do2VO(projectDO);
    }

    @Override
    public ProjectVO serviceMe() {
        Long projectId = SessionContext.getProjectId();
        AssertUtil.assertNotNull(projectId, ErrorCode.LOGIN_INVALID);
        return projectService.getByKey(projectId);
    }

    @Override
    public JiansheUnitVO manageLogin(LoginRequest request) {
        AssertUtil.assertNotNull(request.getAccount(), "账号不能为空");
        AssertUtil.assertNotNull(request.getPassword(), "密码不能为空");

        JiansheUnitDO jiansheUnitDO = jiansheUnitService.lambdaQuery()
                .eq(JiansheUnitDO::getAccount, request.getAccount())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(jiansheUnitDO, ErrorCode.ACCOUNT_NOT_EXIST_ERROR);
        AssertUtil.assertTrue(Objects.equals(request.getPassword(), jiansheUnitDO.getPassword()), ErrorCode.PASSWORD_ERROR);
        return JiansheUnitDtoMapper.INSTANCE.do2VO(jiansheUnitDO);
    }

    @Override
    public JiansheUnitVO manageMe() {
        Long jiansheUnitId = SessionContext.getJiansheUnitId();
        AssertUtil.assertNotNull(jiansheUnitId, ErrorCode.LOGIN_INVALID);
        return jiansheUnitService.getByKey(jiansheUnitId);
    }

    @Override
    public OperateUserVO operateLogin(LoginRequest request) {
        AssertUtil.assertNotNull(request.getAccount(), "账号不能为空");
        AssertUtil.assertNotNull(request.getPassword(), "密码不能为空");

        OperateUserDO operateUserDO = operateUserService.lambdaQuery()
                .eq(OperateUserDO::getAccount, request.getAccount())
                .last("limit 1")
                .one();
        AssertUtil.assertNotNull(operateUserDO, ErrorCode.ACCOUNT_NOT_EXIST_ERROR);
        AssertUtil.assertFalse(BooleanUtils.toBoolean(operateUserDO.getDeleted()), ErrorCode.ACCOUNT_NOT_EXIST_ERROR);
        AssertUtil.assertTrue(Objects.equals(request.getPassword(), operateUserDO.getPassword()), "密码不正确");
        AssertUtil.assertTrue(Objects.equals(operateUserDO.getStatus(), OperateUserStatusEnum.ENABLE.name()), "该账号已禁用");
        OperateUserVO operateUserVO = OperateUserDtoMapper.INSTANCE.do2VO(operateUserDO);

        operateUserVO.setPermissionCodes(getPermission(operateUserDO.getId()));
        return operateUserVO;
    }

    @Override
    public OperateUserVO operateMe() {
        Long operateUserId = SessionContext.getOperateUserId();
        AssertUtil.assertNotNull(operateUserId, ErrorCode.LOGIN_INVALID);
        OperateUserVO operateUserVO = operateUserService.getByKey(operateUserId);
        operateUserVO.setPermissionCodes(getPermission(operateUserVO.getId()));
        return operateUserVO;
    }

    private List<String> getPermission(Long userId) {
        /** 获取权限 */
        Set<OperatePermissionVO> permissionSet = new HashSet<>();
        List<OperateRoleDO> roles = operateRoleMapper.findByUserId(userId);
        for (OperateRoleDO item : CollectionUtils.emptyIfNull(roles)) {
            List<OperatePermissionDO> permissions = operatePermissionMapper.findByRoleId(item.getId());
            for (OperatePermissionDO permission : CollectionUtils.emptyIfNull(permissions)) {
                if (permission.getParentId() != 0) {
                    //兼容处理多层级前端半选的情况
                    OperatePermissionDO parent = operatePermissionMapper.findById(permission.getParentId());
                    if (parent != null) {
                        permissionSet.add(OperatePermissionDtoMapper.INSTANCE.do2VO(parent));
                    }
                }
                permissionSet.add(OperatePermissionDtoMapper.INSTANCE.do2VO(permission));
            }
        }
        return permissionSet.stream()
                .sorted(Comparator.comparing(OperatePermissionVO::getId))
                .map(OperatePermissionVO::getCode)
                .collect(Collectors.toList());
    }
}
